package cn.hxth.dubbo.service.impl;

import cn.hxth.api.model.InstockRecord;
import cn.hxth.api.model.ProductBaseInfo;
import cn.hxth.api.model.Remind;
import cn.hxth.api.query.InstockRecordQueryObject;
import cn.hxth.api.query.PageResult;
import cn.hxth.api.query.QueryObject;
import cn.hxth.api.service.IInstockRecordService;
import cn.hxth.dubbo.service.mapper.InstockRecordMapper;
import cn.hxth.dubbo.service.mapper.PlantMapper;
import cn.hxth.dubbo.service.mapper.ProductMapper;
import cn.hxth.dubbo.service.mapper.RemindMapper;
import cn.hxth.dubbo.service.mq.RabbitMQSender;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Transactional
@Service
public class InstockRecordServiceImpl implements IInstockRecordService {
    @Resource(name = "myRedisTemplate")
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private InstockRecordMapper instockRecordMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private RemindMapper remindMapper;
    @Resource
    private PlantMapper plantMapper;
    @Resource
    private RabbitMQSender rabbitMQSender;

    @Override
    public boolean insertInstockRecord(List<InstockRecord> instockRecordList) {

        boolean flag = this.instockRecordMapper.insertList(instockRecordList);
        if (flag) {
            // 删除redis中入库汇总信息
            this.redisTemplate.delete("in_aggr");
            for (InstockRecord instockRecord : instockRecordList) {
                // 为入库之后发生改变的关联表设值
                ProductBaseInfo productBaseInfo = new ProductBaseInfo();
                productBaseInfo.setInventory(instockRecord.getInventory());
               // productBaseInfo.setLin(instockRecord.getLin());
                //productBaseInfo.setPrice(instockRecord.getPrice());
                productBaseInfo.setPid(instockRecord.getProduct().getPid());
                int inventory = productBaseInfo.getInventory() + instockRecord.getIncount();
                productBaseInfo.setInventory(inventory);
                // 发送商品核心信息改变消息
                this.rabbitMQSender.send("data-change-queue", "{\"event_type\": \"updateProductBaseInfo\",\"data\": " + JSONObject.toJSONString(productBaseInfo) + "}");
                //  判断该入库商品是否为警戒库存，且如果更新之后库存超过警戒数量则删除与之对应的警戒记录
                if (this.remindMapper.selectCountBySid(instockRecord.getProduct().getSpec().getSid()) > 0 && instockRecord.getProduct().getFloor() < inventory) {
                   /* System.out.println("inventory="+inventory);
                    System.out.println("floor="+instockRecord.getProduct().getFloor());
                    System.out.println("sid="+instockRecord.getProduct().getSpec().getSid());*/
                   // 发送警戒库存删除消息
                    this.rabbitMQSender.send("data-change-queue", "{\"event_type\": \"deleteRemind\",\"data\": " + instockRecord.getProduct().getSpec().getSid() + "}");
                    // 如果仍为警戒库存则更新警戒库存信息
                }else if(instockRecord.getProduct().getFloor()>=inventory){
                    Remind remind = new Remind() ;
                    remind.setCount(productBaseInfo.getInventory());
                    remind.setSpec(instockRecord.getProduct().getSpec());
                    remind.setFloor(instockRecord.getProduct().getFloor());
                    remind.setProductSpec(instockRecord.getProductSpec());
                    remind.setProductName(instockRecord.getProductName());
                    this.rabbitMQSender.send("data-change-queue","{\"event_type\": \"updateRemindCountBySid\",  \"data\": " +JSONObject.toJSONString(remind) +   "}");
                }
                // 更新对应车间入库次数
                this.rabbitMQSender.send("data-change-queue", "{\"event_type\": \"updatePlantTime\",\"data\": " + instockRecord.getPlant().getCid() + "}");

            }

        }

        return flag;
    }

    @Override
    public InstockRecord getInstockRecord(int nio) {

        return this.instockRecordMapper.selectByPrimaryKey(nio);
    }

  /*  @Override
    public PageResult findAll(InstockRecordQueryObject instockRecordQueryObject) {
          *//*
        List<InstockRecord> instockRecordLIst = new ArrayList<>() ;

      Set<String> keys = redisTemplate.keys("instockRecordList_*");
        for(String key:keys){
            long saveTime = Long.parseLong(key.split("_")[1]);

            long firstTime = instockRecordQueryObject.getFirstDate().getTime() ;
            long secondTime = instockRecordQueryObject.getSecondDate().getTime() ;
            if(firstTime<=saveTime&&secondTime>=saveTime){
                String jsonStr = (String) this.redisTemplate.opsForValue().get(key);
                List<InstockRecord> instockRecords = JSONArray.parseArray(jsonStr, InstockRecord.class);
                instockRecordLIst.addAll(instockRecordLIst) ;
            }
        }*//*

        int count = this.instockRecordMapper.selectCount(instockRecordQueryObject);
        List<InstockRecord> listData = this.instockRecordMapper.selectAll(instockRecordQueryObject);
        return new PageResult(listData, count, instockRecordQueryObject.getCurrentPage(), instockRecordQueryObject.getPageSize());

    }*/
  public PageResult findAll(InstockRecordQueryObject instockRecordQueryObject) {
          /*
        List<InstockRecord> instockRecordLIst = new ArrayList<>() ;

      Set<String> keys = redisTemplate.keys("instockRecordList_*");
        for(String key:keys){
            long saveTime = Long.parseLong(key.split("_")[1]);

            long firstTime = instockRecordQueryObject.getFirstDate().getTime() ;
            long secondTime = instockRecordQueryObject.getSecondDate().getTime() ;
            if(firstTime<=saveTime&&secondTime>=saveTime){
                String jsonStr = (String) this.redisTemplate.opsForValue().get(key);
                List<InstockRecord> instockRecords = JSONArray.parseArray(jsonStr, InstockRecord.class);
                instockRecordLIst.addAll(instockRecordLIst) ;
            }
        }*/

      int count = this.instockRecordMapper.selectCount(instockRecordQueryObject) ;
      List<Integer> inos = this.instockRecordMapper.selectInoForCache(instockRecordQueryObject) ;
      List<InstockRecord> listData = new ArrayList<>() ;
      for(int ino:inos){
          InstockRecord instockRecord = null ;
          String jsonStr = (String) this.redisTemplate.opsForValue().get("instockRecor_" + ino);
          if(jsonStr==null){
              instockRecord = this.instockRecordMapper.selectByPrimaryKey(ino);
              this.redisTemplate.opsForValue().set("instockRecor_"+ino,JSONObject.toJSONString(instockRecord));
          }
          else {
              instockRecord = JSONObject.parseObject(jsonStr,InstockRecord.class) ;
          }
          listData.add(instockRecord) ;

      }
      // List<OutstockRecord> listData = this.outstockRecordMapper.selectAll(outstockRecordQueryObject);
      return  new PageResult(listData,count,instockRecordQueryObject.getCurrentPage(),instockRecordQueryObject.getPageSize()) ;

  }

    @Override
    public PageResult findAggrInfo(QueryObject queryObject) {
        int start = (queryObject.getCurrentPage() - 1) * queryObject.getPageSize();
        int end = start + queryObject.getPageSize() - 1;
        Integer count = this.instockRecordMapper.selectAggrInfoCount();
        List<Object> inaggrList = this.redisTemplate.opsForList().range("in_aggr", start, end);
        if (inaggrList.size() > 0) {
            return new PageResult(inaggrList, count, queryObject.getCurrentPage(), queryObject.getPageSize());
        }

        List<Map<String, Object>> allData = this.instockRecordMapper.selectAggrInfo();
        this.redisTemplate.opsForList().leftPushAll("in_aggr", allData);
        inaggrList = this.redisTemplate.opsForList().range("in_aggr", start, end);

        return new PageResult(inaggrList, count, queryObject.getCurrentPage(), queryObject.getPageSize());
    }
}
